let YLVue;
// 实现一个 路由插件
class YLVueRouter {
  constructor(options) {
    this.$options = options;

    // 缓存path和route映射关系
    // this.routeMap = {};
    // this.$options.routes.forEach((route) => {
    //   this.routeMap[route.path] = route;
    // });

    // 数据响应式
    // // this.current = '/';
    // const initial = window.location.hash.slice(1) || '/';
    // // $set不行它的对象不能是 Vue 实例，或者 Vue 实例的根数据对象。
    // YLVue.util.defineReactive(this, 'current', initial);
    this.current = window.location.hash.slice(1) || '/';
    YLVue.util.defineReactive(this, 'matched', []);
    // 递归的获取路由数组
    this.match();

    window.addEventListener('hashchange', this.onHashChange.bind(this));
    window.addEventListener('load', this.onHashChange.bind(this));
  }
  onHashChange() {
    // #/about
    this.current = window.location.hash.slice(1);
    this.matched = [];
    this.match();
  }

  match(routes) {
    routes = routes || this.$options.routes;
    // 递归遍历
    for (const route in routes) {
      // 特判  '/'  一般的根路径不会去嵌套
      if (route.path === '/' && this.current === '/') {
        this.matched.push(route);
        return;
      }

      // /about/info
      // 这样执行完毕之后  matched 就装满了匹配上的路由
      if (route.path !== '/' && this.current.indexOf(route.path) !== -1) {
        this.matched.push(route);
        if (route.children && route.children.length > 0) {
          this.match(route.children);
        }
        return;
      }
    }
  }
}

// 插件需要一个静态的install方法，参数是Vue的构造函数
YLVueRouter.install = function(Vue) {
  // 保持构造函数
  YLVue = Vue;

  // 挂载 $router
  // 问题：install方法是 use的时候执行  在执行这里的时候  实例对象还没有被创建
  Vue.mixin({
    beforeCreate() {
      // 做一个全局的混入，组件实例化的时候才执行，这个时候 router实例已经被创建了
      // this是指组件实例
      // $options 是在 main.js  中 new Vue传入的对象
      if (this.$options.router) {
        // 避免 $router 被多次的挂载到原型上
        Vue.prototype.$router = this.$options.router;
      }
    },
  });

  // 实现两个全局组件
  Vue.component('router-link', {
    props: {
      to: { type: String, required: true },
    },
    render(h) {
      // 支持jsx语法  需要一个 loader库
      // return <a href={'#' + this.to}>{this.$slots.default}</a>;
      return h('a', { attrs: { href: '#' + this.to } }, this.$slots.default);
    },
  });
  Vue.component('router-view', {
    render(h) {
      // 获取 路由表  根据url 匹配路由
      // const routes = this.$router.$options.routes;
      // const current = this.$router.current;
      // const route = routes.find((route) => route.path === current);
      // const comp = route ? route.component : null;

      // 标记当前 router-view 的深度
      this.$vnode.data.routerView = true;
      let depth = 0;
      let parent = this.$parent;
      while (parent) {
        const vnodeData = parent.$vnode && parent.$vnode.data;
        if (vnodeData) {
          if (vnodeData.routerView) {
            // 说明当前的 parent 是一个router-view
            depth++;
          }
        }
        parent = this.$parent;
      }

      // const { routeMap, current } = this.$router;
      // const comp = routeMap[current] ? routeMap[current].component : null;

      const route = this.$router.matched(depth);
      let comp = route ? route.component : null;
      return h(comp);
    },
  });
};

export default YLVueRouter;
